import { dom, Nodes } from '@knno/dom';
import { FormItem } from '../interface';
import { buttonStyle } from './button.css';
import { Checkable } from '../checkbox/checkable';
import SVGMenuDown from '@mdi/svg/svg/menu-down.svg';

export type ButtonType =
	| 'info'
	| 'primary'
	| 'warning'
	| 'danger'
	| 'success'
	| 'primary-text'
	| 'warning-text'
	| 'danger-text'
	| 'success-text'
	| 'info-text'
	| 'primary-outline'
	| 'warning-outline'
	| 'danger-outline'
	| 'success-outline';
export type IconPos = 'left' | 'top';

export class Button extends Checkable implements FormItem {
	protected override get box(): Nodes {
		return this.query(':scope>div');
	}
	updateFacade(): void {
		// do nothing
	}
	constructor() {
		super(
			dom
				.button(buttonStyle)
				.attr({
					'icon-pos': 'left',
				})
				.append(dom.div())
		);
		this.on('update', (evt) => {
			this.checked(evt.detail.checked);
		});
		// Object.defineProperty(this[0], REF, { value: this });
	}

	disabled(): boolean;
	disabled(value: boolean): this;
	disabled(value?: boolean): boolean | this {
		if (value === undefined) {
			return this.attr('disabled') != null;
		}
		return this.attr('disabled', value);
	}

	icon(icon: string | null) {
		const svg = this.query(':scope>svg[name=icon]');
		this.remove(svg);
		if (icon) {
			dom.wrap(...this).insert(dom.html(icon).name('icon'));
		}
		return this;
	}

	menu(): boolean;
	menu(value: boolean): this;
	menu(value?: boolean): boolean | this {
		if (value === undefined) {
			return this.attr('menu') != null;
		}
		const svg = this.query(':scope>svg[name=menu]');
		this.remove(svg);
		if (value && this.iconPos() !== 'top') {
			dom.wrap(...this).append(dom.html(SVGMenuDown).name('menu'));
		}
		return this.attr('menu', value);
	}

	type(): string;
	type(type: ButtonType): this;
	type(type?: ButtonType) {
		if (type) {
			this.attr('face', type);
			return this;
		} else return this.attr('face');
	}

	iconPos(): IconPos;
	iconPos(pos: IconPos): this;
	iconPos(pos?: IconPos) {
		if (pos) {
			this.attr('icon-pos', pos === 'top' ? pos : null);
			this.menu(this.menu());
			return this;
		} else return this.attr('icon-pos');
	}

	override text(text: string): this;
	override text(): string;
	override text(text?: string): this | string | undefined {
		const div = this.query(':scope>div').takeIf() ?? dom.div().appendTo(this.elems());
		if (typeof text === 'string') {
			div.text(text);
			return this;
		}
		return div.text();
	}

	checked(): boolean;
	checked(value: boolean): this;
	checked(value?: boolean): this | boolean {
		const currentValue = this.attr('checked') === 'true';
		if (value === undefined) {
			return currentValue;
		} else {
			if (currentValue !== value) {
				this.attr('checked', value ? 'true' : null);
			}
			return this;
		}
	}
}

export function button(...className: string[]): Button {
	return new Button().addClass(...className);
}
